package org.ejs.bean;


import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.StatefulTimeout;
import javax.persistence.PostRemove;

import org.ejs.network.ServerAddress;

@Stateful(mappedName = "FileManager")
@StatefulTimeout(unit = java.util.concurrent.TimeUnit.MINUTES, value = -1)
@LocalBean
public class FileManager implements FileManagerRemote {

	private ServerAddress client;
	private List<String> files;
	private FileManagerRemote next;
	private FileManagerRemote previous;
	
	@EJB
	ServerManagerRemote master;

	public FileManager() {
	}

	@PostConstruct
	public void postConstruct() {
		files = new ArrayList<String>();
	}

	@Override
	public void connect(ServerAddress from) {

	}

	@Override
	public void disconnect() {
		//TODO : Appeler le master
		master.disconnect(client);
	}


	@Override
	public void add(String name) {
		files.add(name);
	}

	@Override
	public void delete(String name) {
		files.remove(name);
	}

	@Override
	public List<String> list() {
		return list(client,0);
	}

	@Override
	public List<String> list(ServerAddress addr, int cpt) {
		if (addr.equals(client) && cpt!=0) {
			return new ArrayList<String>();
		}
		if (addr.equals(client)) {
			cpt=1;
		}
		List<String> remoteFiles = next.list(addr,cpt);
		remoteFiles.addAll(files);
		return remoteFiles;
	}

	public boolean copy(String file, ServerAddress from) {
		return copy(file, from, client);
	}

	@Override
	public boolean copy(String file, ServerAddress from, ServerAddress to) {
		if (to.equals(client)) {
			add(file);
			return true;
		}
		if (from.equals(client)) {
			return false;
		}
		return next.copy(file, from, to);
	}

	@Override
	public boolean move(String file, ServerAddress addr, ServerAddress to) {
		/*if (copy(file, addr)) {
			System.out.println("move");
			System.out.println(file);
			System.out.println(this.files.indexOf(file));
			delete(file);
			return true;
		}
		return false;*/
		if (to.equals(client)) {
			System.out.println("OUVRE TES YEUX");
			System.out.println(this.getAddress().port);
			findA(file,addr);
			add(file);
			return true;
		}
		if (addr.equals(client)) {
			return false;
		}
		return next.move(file, addr, to);
	}
	
	public boolean move(String file, ServerAddress addr) {
		return move(file, addr, client);
	}

	@Override
	public void setNext(FileManagerRemote next) {
		this.next = next;
	}

	@Override
	public FileManagerRemote getNext() {
		return next;
	}

	@Override
	public ServerAddress getAddress() {
		return this.client;
	}

	@Override
	public void setAddress(ServerAddress client) {
		this.client = client;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.client == null) ? 0 : this.client.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof FileManager))
			return false;
		FileManager other = (FileManager) obj;
		if (this.client == null) {
			if (other.client != null)
				return false;
		} else if (!this.client.equals(other.client))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return client.toString();
	}

	public String getTest(){
		return "gezhyrdg";
	}

	public ServerAddress getClient() {
		return client;
	}

	public void setClient(ServerAddress client) {
		this.client = client;
	}

	@Override
	public ServerAddress find(String name, FileManagerRemote me) {
		if(me.equals(this))
			return null;
		if(this.files.contains(name))
			return this.getAddress();
		return this.next.find(name, me);
	}
	
	@PostRemove
	public void preDestroy(){
		master.disconnect(client);
	}

	@Override
	public void setPrevious(FileManagerRemote previous) {
		this.previous=previous;
		
	}

	@Override
	public FileManagerRemote getPrevious() {
		return previous;
	}
	public List<String> getFiles() {
		return files;
	}
	
	public boolean findA(String name, ServerAddress me){
		if(me.equals(client))
		{
			delete(name);
			return true;
		}
		return this.next.findA(name, me);
	}
}
